package com.m1book.domain.util;

import java.io.IOException;
import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.m1book.domain.book.Book;
import com.m1book.domain.book.DoubanBookInfo;

public class DoubanBookUtil {
	private final static Logger logger = LoggerFactory.getLogger(DoubanBookUtil.class);
	
	public static Document parse(String xmlSource) {
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			
			StringReader reader = new StringReader(xmlSource.trim());
			InputSource source = new InputSource(reader);
			return builder.parse(source);
		} catch (ParserConfigurationException e) {
			logger.error(e.getMessage());
		} catch (SAXException e) {
			logger.error(e.getClass().getName() + ": " + e.getMessage());
		} catch (IOException e) {
			logger.error(e.getMessage());
		}
		
		return null;
	}
	
	public static Document pareseByURI(String uri) {
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			
			return builder.parse(uri);
		} catch (ParserConfigurationException e) {
			logger.error(e.getMessage());
		} catch (SAXException e) {
			logger.error(e.getClass().getName() + ": " + e.getMessage());
		} catch (IOException e) {
			logger.error(e.getMessage());
		}
		
		return null;
	}
	
	public static Book buildBook(Document document) {
		Book book = new Book();
		DoubanBookInfo info = new DoubanBookInfo();
		book.setDoubanBookInfo(info);
		
		String doubanId = document.getElementsByTagName("id").item(0).getTextContent();
		info.setDoubanId(doubanId);
		
		String title = document.getElementsByTagName("title").item(0).getTextContent();
		book.setTitle(title);
		info.setTitle(title);
		
		String summary = document.getElementsByTagName("summary").item(0).getTextContent();
		info.setSummary(summary);
		
		NodeList list = document.getElementsByTagName("link");
		for (int i = 0; i < list.getLength(); i++) {
			Node node = list.item(i);
			NamedNodeMap map = node.getAttributes();
			String attrRel = map.getNamedItem("rel").getNodeValue();
			String attrHref = map.getNamedItem("href").getNodeValue();
			if (attrRel.equalsIgnoreCase("image")) {
				info.setImageLink(attrHref);
			}
		}
		
		list = document.getElementsByTagName("db:attribute");
		for (int i = 0; i < list.getLength(); i++) {
			Node node = list.item(i);
			NamedNodeMap map = node.getAttributes();
			String attrName = map.getNamedItem("name").getNodeValue();
			String nodeText = node.getTextContent();
			
			if (attrName.equalsIgnoreCase("isbn10")) {
				info.setIsbn10(nodeText);
				book.setIsbn10(nodeText);
			} else if (attrName.equalsIgnoreCase("isbn13")) {
				info.setIsbn13(nodeText);
				book.setIsbn13(nodeText);
			} else if (attrName.equalsIgnoreCase("subtitle")) {
				info.setSubTitle(nodeText);
			} else if (attrName.equalsIgnoreCase("author-intro")) {
				info.setAuthorInfo(nodeText);
			} else if (attrName.equalsIgnoreCase("author")) {
				book.setAuthor(nodeText);
				info.setAuthor(nodeText);
			} else if (attrName.equalsIgnoreCase("price")) {
				info.setPrice(Float.valueOf(nodeText.split("元")[0]));
			} else if (attrName.equalsIgnoreCase("publisher")) {
				info.setPublisher(nodeText);
			} else if (attrName.equalsIgnoreCase("binding")) {
				info.setBinding(nodeText);
			} else if (attrName.equalsIgnoreCase("pubdate")) {
				info.setPubdate(nodeText);
			}
		}
		
		list = document.getElementsByTagName("db:tag");
		for (int i = 0; i < list.getLength(); i++) {
			Node node = list.item(i);
			NamedNodeMap map = node.getAttributes();
			String nameValue = map.getNamedItem("name").getNodeValue();
			String countValue = map.getNamedItem("count").getNodeValue();
			
			Integer count = Integer.parseInt(countValue);
			info.getTags().put(nameValue, count);
		}
		
		return book;
	}

}
